# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: jaewon

import datetime

from coin.base.datetime_util import to_datetime
from coin.exchange.okex_futures.kr_rest.futures_product import (OkexFuturesProduct)
from coin.exchange.bitmex.kr_rest.futures_product import BitmexFuturesProduct
from coin.strategy.mm.simple_sim import result_util
from coin.strategy.mm.simple_sim.strategy.pass_unhedge_2 import (PassUnhedgedSimStrategy)


def get_products():
  return [
      OkexFuturesProduct.FromStr('BTC-USD.QUARTER'),
      BitmexFuturesProduct.FromStr('BTC-USD.PERPETUAL')
  ]


def get_machines():
  return ['feed-3.eu-west-1']


def get_time_ranges():
  ranges = []
  cur_dt = datetime.datetime(2018, 4, 12, 0, 0, 0)
  end_dt = datetime.datetime(2018, 4, 16, 0, 0, 0)
  while cur_dt < end_dt:
    ranges.append((cur_dt, cur_dt + datetime.timedelta(hours=24)))
    cur_dt += datetime.timedelta(hours=24)
  return ranges


def get_strategy(from_ts, to_ts):
  products = get_products()
  ref_product = products[0]
  ref_product_true_book_funcs = ((lambda book: book.get_notional_asks_by_qty(200.)[1][-1][0]),
                                 (lambda book: book.get_notional_bids_by_qty(200.)[1][-1][0]))

  pass_product = products[1]
  pass_product_true_book_funcs = ((lambda book: book.get_notional_asks_by_qty(10000.)[1][-1][0]),
                                  (lambda book: book.get_notional_bids_by_qty(10000.)[1][-1][0]))

  NS_PER_SECOND = (10**9)
  NS_PER_MINUTE = 60 * NS_PER_SECOND

  strategy_list = []

  for basis_ma_window in [2, 5, 10, 15]:
    for edge_bp in [5, 7, 9, 11, 13]:
      pricing_param = {
          'basis_ma_window': basis_ma_window * NS_PER_MINUTE,
          'tick': 0.5,
          'book_askt_func_1': ref_product_true_book_funcs[0],
          'book_bidt_func_1': ref_product_true_book_funcs[1],
          'book_askt_func_2': pass_product_true_book_funcs[0],
          'book_bidt_func_2': pass_product_true_book_funcs[1]
      }

      executor_param = {
          'lot_size': 0.1,
          'min_pos': -1.,
          'max_pos': 1.,
          'maker_fee': -2.5 / 10000.,
          'taker_fee': 7.5 / 10000.,
          'execution_delay': 1 * NS_PER_SECOND,
          'post_only': True,
          'trade_qty_func': (lambda trade: trade.qty / trade.price)
      }

      agg_edge_bp = 17
      name = '%02dm.%02dbp.%02dbp.%s' % (
          basis_ma_window, edge_bp, agg_edge_bp, to_datetime(from_ts).strftime('%Y%m%d'))

      strategy = PassUnhedgedSimStrategy(pass_product,
                                         ref_product,
                                         edge_bp / 10000.,
                                         agg_edge_bp / 10000.,
                                         pricing_param,
                                         executor_param,
                                         trade_after=basis_ma_window,
                                         name=name)
      strategy_list.append(strategy)

  return strategy_list


def get_strategy_result(strategy):
  return {'name': strategy.name, **strategy.get_summary()}


def aggregate_result(results):
  return result_util.aggregate_sim_result(results)
